#ifndef _TYPES_H_
#define _TYPES_H_

typedef int          boolean;

// 最大文件或目录名长度
#define MAX_NAME_LEN 128

struct custom_options
{
    const char *device;
};

#define TRUE                    1
#define FALSE                   0

#define NFS_ERROR_NONE          0
#define NFS_ERROR_ACCESS        EACCES
#define NFS_ERROR_SEEK          ESPIPE     
#define NFS_ERROR_ISDIR         EISDIR
#define NFS_ERROR_NOSPACE       ENOSPC
#define NFS_ERROR_EXISTS        EEXIST
#define NFS_ERROR_NOTFOUND      ENOENT
#define NFS_ERROR_UNSUPPORTED   ENXIO
#define NFS_ERROR_IO            EIO     /* Error Input/Output */
#define NFS_ERROR_INVAL         EINVAL  /* Invalid Args */

#define NFS_DATA_PER_FILE       6       /* 采用直接索引方式，一个文件最多使用 6个数据块 */
#define NFS_DEFAULT_PERM        0777


// 文件类型常量
#define NFS_FILE 1
#define NFS_DIR 2

// 逻辑块大小
#define SZ_BLK 1024

// 虚拟磁盘大小：4 MB
#define SZ_DISK (4 * 1024 * 1024)

// 一个逻辑块可以存储 8192 个 inode
#define MAX_INODE (8 * 1024)

/**
 * @struct nfs_super_d
 * @brief 磁盘上的超级块结构体。
 *
 * 存储在磁盘上的超级块信息，用于描述文件系统的基本布局和状态。
 */
struct nfs_super_d
{
    uint32_t magic; /* 幻数 */

    int inode_bitmap_blks;   /* inode 位图占用的块数 */
    int inode_bitmap_offset; /* inode 位图在磁盘中的起始块号 */
    int data_bitmap_blks;    /* 数据位图占用的块数 */
    int data_bitmap_offset;  /* 数据位图在磁盘中的起始块号 */
};

/**
 * @struct nfs_super
 * @brief 内存中的超级块结构体。
 *
 * 存储在内存中的超级块信息，用于快速访问和管理文件系统的元数据。
 */
struct nfs_super
{
    int fd; /* 文件描述符，指向虚拟磁盘设备文件 */

    char *inode_bitmap;             /* inode 位图在内存中的地址 */
    char *data_bitmap;              /* 数据位图在内存中的地址 */
    struct nfs_dentry *root_dentry; /* 指向根目录的目录项 */

    int inode_bitmap_blks;   /* inode 位图占用的块数 */
    int inode_bitmap_offset; /* inode 位图在磁盘中的起始块号 */
    int data_bitmap_blks;    /* 数据位图占用的块数 */
    int data_bitmap_offset;  /* 数据位图在磁盘中的起始块号 */
    int inode_blks;          /* inode 区域占用的块数 */
    int inode_offset;        /* inode 区域在磁盘中的起始块号 */
    int data_blks;           /* 数据区占用的块数 */
    int data_offset;         /* 数据区在磁盘中的起始块号 */
};

/**
 * @struct nfs_inode_d
 * @brief 磁盘上的 inode 结构体。
 *
 * 存储在磁盘上的 inode 信息，包含文件或目录的元数据。
 */
struct nfs_inode_d
{
    uint32_t ino;     /* inode 编号（唯一标识符） */
    int size;         /* 文件大小（字节数） */
    int type;         /* 文件类型，NFS_FILE 或 NFS_DIR */
    int dircnt;       /* 目录项数量，仅目录有效 */
    int datablock[NFS_DATA_PER_FILE]; /* 直接数据块编号数组，最多指向 6 个数据块 */
};

/**
 * @struct nfs_inode
 * @brief 内存中的 inode 结构体。
 *
 * 存储在内存中的 inode 信息，包含指向数据块内容的指针等运行时信息。
 */
struct nfs_inode
{
    uint32_t ino;                   /* inode 编号（唯一标识符） */
    int size;                       /* 文件大小（字节数） */
    int type;                       /* 文件类型，NFS_FILE 或 NFS_DIR */
    int dircnt;                     /* 目录项数量，仅目录有效 */
    struct nfs_dentry *dentry_pt;   /* 指向该 inode 对应的目录项（父目录项） */
    struct nfs_dentry *dentry_sons; /* 指向该目录下的子目录项链表 */
    int datablock[NFS_DATA_PER_FILE];               /* 直接数据块编号数组，最多指向 6 个数据块 */
    char *datablock_pt[NFS_DATA_PER_FILE];          /* 指向数据块内容在内存中的地址 */
};

/**
 * @struct nfs_dentry_d
 * @brief 磁盘上的目录项结构体。
 *
 * 存储在磁盘上的目录项信息，将文件名或目录名与 inode 编号关联起来。
 */
struct nfs_dentry_d
{
    char name[MAX_NAME_LEN]; /* 文件或目录名称 */
    int type;                /* 类型，NFS_FILE 或 NFS_DIR */
    int ino;                 /* 对应的 inode 编号 */
};

/**
 * @struct nfs_dentry
 * @brief 内存中的目录项结构体。
 *
 * 存储在内存中的目录项信息，包含指向 inode 和其他目录项的指针，用于构建目录结构。
 */
struct nfs_dentry
{
    char name[MAX_NAME_LEN];    /* 文件或目录名称 */
    int type;                   /* 类型，NFS_FILE 或 NFS_DIR */
    int ino;                    /* 对应的 inode 编号 */
    struct nfs_inode *inode_pt; /* 指向该目录项对应的 inode */
    struct nfs_dentry *nxt;     /* 指向下一个兄弟目录项，用于链表 */
    struct nfs_dentry *fa;      /* 指向父目录的目录项 */
};

#endif /* _TYPES_H_ */